package texas

import (
	"fmt"
)


var CARDTYPE = []string{"", "高牌", "一对", "两对", "三条", "顺子", "同花", "葫芦", "四条", "同花顺", "皇家同花顺"}
type Desk struct {
	gambpool int
	index int
	dm *DealMachine
	playerAllIn bool
	aiAllin bool
	current int

	players []IPlayer

}

func NewDesk() *Desk{
	desk := &Desk{}
	return desk
}

func (desk *Desk) PlayGame(){

	desk.dm = NewDealMachine()
	desk.dm.Init()

	aai := GetAI()
	player := GetPlayer()
	desk.players = append(desk.players, aai)
	desk.players = append(desk.players, player)

	desk.current = 0
	aiPlayer := aai.(*AI)
	p := player.(*Player)
	for {
		if p.GetChip()<=0 || aiPlayer.GetChip()<=0{
			break
		}

		fmt.Printf("\n\n")
		fmt.Println("新局开始！")
		desk.dm.Shuffle()
		aiPlayer.Init()
		p.Init()

		desk.gambpool = 0
		desk.index = 0
		desk.aiAllin = false
		desk.playerAllIn = false

		//盲注
		p.Blind(100)
		aiPlayer.Blind(100)
		desk.gambpool += 200

		//hole下注
		p.SetHole(desk.dm.Deal(), desk.dm.Deal())
		aiPlayer.SetHole(desk.dm.Deal(), desk.dm.Deal())
		if p.GetChip()==0 || aiPlayer.GetChip()==0{
			desk.index = 2
			desk.allin(p, aai)
			continue
		}

		desk.showTable(p, aai)
		bet := desk.chipIn(p, aai, desk.current)
		if bet == 0{
			continue
		}
		desk.gambpool += 2*bet
		p.Call(bet)
		aiPlayer.Call(bet)
		desk.index += 2
		if desk.playerAllIn == true || desk.aiAllin == true{
			desk.allin(p, aai)
			continue
		}

		//flop下注
		c1 := desk.dm.Deal()
		c2 := desk.dm.Deal()
		c3 := desk.dm.Deal()

		p.SetFlop(c1, c2, c3)
		aiPlayer.SetFlop(c1, c2, c3)
		desk.showTable(p, aai)
		bet = desk.chipIn(p, aai, desk.current)
		if bet == 0{
			continue
		}
		desk.gambpool += 2*bet
		p.Call(bet)
		aiPlayer.Call(bet)
		desk.index += 3
		if desk.playerAllIn ==true || desk.aiAllin == true{
			desk.allin(p, aai)
			continue
		}

		//turn下注
		c1 = desk.dm.Deal()
		p.SetTurn(c1)
		aiPlayer.SetTurn(c1)
		desk.showTable(p, aai)
		bet = desk.chipIn(p, aai, desk.current)
		if bet == 0{
			continue
		}
		desk.gambpool += 2*bet
		p.Call(bet)
		aiPlayer.Call(bet)
		desk.index++
		if desk.playerAllIn==true || desk.aiAllin==true{
			desk.allin(p, aai)
			continue
		}

		//river下注
		c1 = desk.dm.Deal()
		p.SetRiver(c1)
		aiPlayer.SetRiver(c1)
		desk.showTable(p, aai)
		bet = desk.chipIn(p, aai, desk.current)
		if bet == 0{
			continue
		}
		desk.gambpool += 2*bet
		p.Call(bet)
		aiPlayer.Call(bet)
		desk.index++

		desk.showdown(p, aai)
	}

	if p.GetChip()>0 {
		fmt.Println("你真牛")
	}else{
		fmt.Println("你太弱了")
	}

	fmt.Println("请按任意键退出")
	var tt string
	fmt.Scan(&tt)
}

func (desk *Desk)chipIn(p *Player, aai IPlayer, mod int) int{

	aiPlayer := aai.(*AI)
	var bet int
	var fcr int
	if mod == 0{
		fmt.Println("请下注，弃牌请输入0")
		fmt.Scan(&bet)
		if bet == 0{
			desk.current = 1
			aiPlayer.Take(desk.gambpool)
			fmt.Println("玩家弃牌，电脑获胜")
			return 0
		}
		if bet >= p.GetChip(){
			bet = p.GetChip()
			desk.playerAllIn = true
		}
		fcr = aiPlayer.FCR(bet, desk.gambpool, desk.dm)
		if fcr == 0{
			desk.current = 0
			p.Take(desk.gambpool)
			fmt.Println("电脑弃牌，玩家获胜")
			return 0
		}
		if fcr >= aiPlayer.GetChip(){
			fmt.Println("来吧！ALL IN 我跟你拼了")
			fcr = aiPlayer.GetChip()
			desk.aiAllin = true
		}
		if desk.playerAllIn == false && fcr > bet{
			desk.current = desk.current^1
			var yn string
			for{
				fmt.Printf("电脑加注为：%d,是否跟注？y/n\n",fcr)
				fmt.Scan(&yn)
				if yn == "y"{
					break
				}else if yn == "n"{
					desk.current = 1
					aiPlayer.Take(desk.gambpool)
					fmt.Println("玩家弃牌，电脑获胜")
					return 0
				}
			}
			if fcr >= p.GetChip(){
				bet = p.GetChip()
				desk.playerAllIn = true
			}else{
				bet = fcr
			}
		}
	}else{
		fcr = aiPlayer.FCR(0, desk.gambpool, desk.dm)
		if fcr == 0{
			desk.current = 0
			p.Take(desk.gambpool)
			fmt.Println("电脑弃牌，玩家获胜")
			return 0
		}
		if fcr >= aiPlayer.GetChip(){
			fmt.Println("来吧！ALL IN 我跟你拼了")
			fcr = aiPlayer.GetChip()
			desk.aiAllin = true
		}
		fmt.Printf("电脑下注为：%d,请跟注或者加注,跟注为0表示弃牌\n",fcr)
		for {
			fmt.Scan(&bet)
			if bet==0 {
				desk.current = 1
				aiPlayer.Take(desk.gambpool)
				fmt.Println("玩家弃牌，电脑获胜")
				return 0
			}
			if bet >= p.GetChip(){
				break
			}
			if bet < fcr{
				fmt.Println("跟注不能小于电脑下注")
			}else{
				break
			}
		}
		if bet >= p.GetChip(){
			bet = p.GetChip()
			desk.playerAllIn = true
		}
		if fcr < bet && desk.aiAllin == false{
			tmp := aiPlayer.FCR(bet, desk.gambpool+bet, desk.dm)
			if tmp==0 {
				p.Take(desk.gambpool)
				desk.current = 0
				fmt.Println("电脑弃牌，玩家获胜")
				return 0
			}
			if bet>=aiPlayer.GetChip(){
				fmt.Println("来吧！ALL IN 我跟你拼了")
				fcr = aiPlayer.GetChip()
				desk.aiAllin = true
			}else{
				fcr = bet
			}
		}
	}
	if desk.aiAllin == true || desk.playerAllIn == true{
		if bet < fcr{
			return bet
		}
		return fcr
	}
	return bet
}

func (desk *Desk)allin(p *Player, aai IPlayer){
	fmt.Println("*****************All in********************")
	aiPlayer := aai.(*AI)
	if desk.index == 2{
		c1 := desk.dm.Deal()
		c2 := desk.dm.Deal()
		c3 := desk.dm.Deal()
		p.SetFlop(c1, c2, c3)
		aiPlayer.SetFlop(c1, c2, c3)
		desk.index += 3
	}
	if desk.index == 5{
		c := desk.dm.Deal()
		p.SetTurn(c)
		aiPlayer.SetTurn(c)
		desk.index++
	}
	if desk.index == 6 {
		c := desk.dm.Deal()
		p.SetRiver(c)
		aiPlayer.SetRiver(c)
	}
	desk.showdown(p, aai)
}

func (desk *Desk) showdown(p *Player, aai IPlayer){
	p.DealOver()
	aiPlayer := aai.(*AI)
	aiPlayer.DealOver()

	if p.GetPower() > aiPlayer.GetPower(){
		desk.current = 0
		p.Take(desk.gambpool)
		fmt.Println("玩家获胜")
	}else if p.GetLevel() == aiPlayer.GetLevel() && p.GetFinalValue() == aiPlayer.GetFinalValue(){
		p.Take(desk.gambpool/2)
		aiPlayer.Take(desk.gambpool/2)
		fmt.Println("平局")
	}else{
		desk.current = 1
		aiPlayer.Take(desk.gambpool)
		fmt.Println("电脑获胜")
	}
	aiPlayer.ShowComminityCards()
	aiPlayer.ShowHole()
	p.ShowHole()
	fmt.Printf("电脑牌型为：%s %v \n", CARDTYPE[aiPlayer.GetLevel()], aiPlayer.GetFinalValue())
	fmt.Printf("你的牌型为：%s %v \n", CARDTYPE[p.GetLevel()], p.GetFinalValue())
	aiPlayer.ShowHand()
	p.ShowHand()
	p.TurnToValue2()
	fmt.Println("card power:",p.GetPower(), aiPlayer.GetPower())
}

func checkError(e error){
	if e != nil{
		fmt.Println(e)
	}
}

func (desk *Desk)showTable(p *Player, aai IPlayer){
	fmt.Println()
	fmt.Println()
	fmt.Println()
	aiPlayer := aai.(*AI)
	fmt.Printf("***********************************************************\n")
	aiPlayer.ShowChip(desk.dm, desk.gambpool)
	fmt.Println()
	fmt.Println()
	fmt.Printf("当前赌池金额为：%d\n",desk.gambpool)
	aiPlayer.ShowComminityCards()
	fmt.Println()
	fmt.Println()
	fmt.Println()
	p.ShowChip()
	p.ShowHole()
	fmt.Printf("***********************************************************\n")
}